package registry

import (
	"fmt"
	"github.com/emicklei/go-restful"
	"kubeInstall/pkg/logger"
	"kubeInstall/server/handlers"
	"kubeInstall/server/models/registry"
	"net/http"
	"strconv"
)

type repositoryHandler struct {
	handlers.BaseHandler
}

func NewRepositoryHandler() handlers.IBaseHandler {
	return new(repositoryHandler)
}

func (h *repositoryHandler)AddToRoute(ws *restful.WebService) {

	ws.Route(ws.GET("/registry/projects/{project_name}/repositories").To(h.listRepositories))
	ws.Route(ws.GET("/registry/projects/{project_name}/repositories/{repository_name}").To(h.getRepository))
	ws.Route(ws.PUT("/registry/projects/{project_name}/repositories/{repository_name}").To(h.updateRepository))
	ws.Route(ws.DELETE("/registry/projects/{project_name}/repositories/{repository_name}").To(h.deleteRepository))
	ws.Route(ws.GET("/registry/projects").To(h.listProjects))
	ws.Route(ws.POST("/registry/projects").To(h.createProject))
	ws.Route(ws.HEAD("/registry/projects").To(h.checkProjectIfExsist))
	logger.Info("add docker registry module successfully")
}

func (h *repositoryHandler) listProjects(r *restful.Request, resp *restful.Response) {

	opts := new(registry.ListProjectOpts)
	opts.Name = r.QueryParameter("name")
	opts.Owner = r.QueryParameter("owner")
	opts.PageSize, _ = strconv.Atoi(r.QueryParameter("page_size"))
	opts.Page, _ = strconv.Atoi(r.QueryParameter("page"))
	opts.Public, _ = strconv.ParseBool(r.QueryParameter("public"))

	projectDetails, err := registry.ListProject(opts)

	if err != nil {
		h.RenderError(resp, err.Error(), http.StatusBadRequest)
		return
	}

	h.RenderResp(resp, projectDetails, http.StatusOK)

}
func (h *repositoryHandler) createProject(r *restful.Request, resp *restful.Response) {

	var opts registry.CreateProjectOpts

	if err := r.ReadEntity(&opts); err != nil {
		h.RenderError(resp, fmt.Sprintf("read create info failed! error is: %v", err), http.StatusBadRequest)
		return
	}

	err := registry.CreateProject(opts)

	if err != nil {
		h.RenderError(resp, err.Error(), http.StatusBadRequest)
		return
	}

	h.RenderResp(resp, handlers.SuccessResp{
		StatusCode: http.StatusOK,
		Message:    fmt.Sprintf("Create %s Success", opts.ProjectName),
	}, http.StatusOK)

}

func (h *repositoryHandler) checkProjectIfExsist(r *restful.Request, resp *restful.Response) {

}

func (h *repositoryHandler) listRepositories(r *restful.Request, resp *restful.Response) {

	opts := new(registry.ListRepositoryOpts)
	projectName := r.PathParameter("project_name")
	opts.PageSize, _ = strconv.Atoi(r.QueryParameter("page_size"))
	opts.Page, _ = strconv.Atoi(r.QueryParameter("page"))

	projectDetails, err := registry.ListRepository(projectName, opts)

	if err != nil {
		h.RenderError(resp, err.Error(), http.StatusBadRequest)
		return
	}

	h.RenderResp(resp, projectDetails, http.StatusOK)

}

func (h *repositoryHandler) getRepository(r *restful.Request, resp *restful.Response) {

	projectName := r.PathParameter("project_name")
	repositoryName := r.PathParameter("repository_name")

	projectDetails, err := registry.GetRepository(projectName, repositoryName)

	if err != nil {
		h.RenderError(resp, err.Error(), http.StatusBadRequest)
		return
	}

	h.RenderResp(resp, projectDetails, http.StatusOK)
}

func (h *repositoryHandler) updateRepository(r *restful.Request, resp *restful.Response) {
	projectName := r.PathParameter("project_name")
	repositoryName := r.PathParameter("repository_name")

	var opts registry.CreateRepositoryOpts

	if err := r.ReadEntity(&opts); err != nil {
		h.RenderError(resp, "read update info from request failed", http.StatusBadRequest)
		return
	}

	err := registry.UpdateRepository(projectName, repositoryName, opts)

	if err != nil {
		h.RenderError(resp, err.Error(), http.StatusBadRequest)
		return
	}

	h.RenderResp(resp, handlers.SuccessResp{
		StatusCode: http.StatusOK,
		Message:    fmt.Sprintf("Update %s Success", repositoryName),
	}, http.StatusOK)

}

func (h *repositoryHandler) deleteRepository(r *restful.Request, resp *restful.Response) {
	projectName := r.PathParameter("project_name")
	repositoryName := r.PathParameter("repository_name")

	err := registry.DeleteRepository(projectName, repositoryName)

	if err != nil {
		h.RenderError(resp, err.Error(), http.StatusBadRequest)
		return
	}

	h.RenderResp(resp, handlers.SuccessResp{
		StatusCode: http.StatusOK,
		Message:    fmt.Sprintf("Delete %s Success", repositoryName),
	}, http.StatusOK)

}
